package com.example.joke.custom.textview

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import com.example.joke.R

class CustomTextView : View {

    private var mText: String? = null
    private var mTextColor: Int = Color.BLACK
    private var mTextSize: Int = 15
    private var mPaint: Paint
    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        // 获取自定义属性
        val typedArray = context?.obtainStyledAttributes(attrs, R.styleable.CustomTextView)
        mText = typedArray?.getString(R.styleable.CustomTextView_cText) ?: ""
        mTextColor = typedArray?.getColor(R.styleable.CustomTextView_cTextColor, mTextColor)!!
//        mTextSize = typedArray?.getDimensionPixelSize(R.styleable.CustomTextView_cTextSize, sp2px(mTextSize))!!
        mTextSize = typedArray?.getDimensionPixelSize(R.styleable.CustomTextView_cTextSize, mTextSize)!!
        // 回收
        typedArray.recycle()

        mPaint = Paint()
        // 抗锯齿
        mPaint.isAntiAlias = true
        mPaint.textSize = mTextSize.toFloat()
        mPaint.color = mTextColor
    }

    private fun sp2px(mTextSize: Int): Int {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize.toFloat(), resources.displayMetrics)
            .toInt()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 布局的宽高都是由这个方法指定，
        // 指定控件的宽高，需要测量，
        // 获取宽高的模式
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        // 1.确定的值，这个时候不需要计算，给的多少就是多少
        var width = MeasureSpec.getSize(widthMeasureSpec)
        // 2.给的是wrap_content，需要计算
        if (widthMode == MeasureSpec.AT_MOST) {
            // 计算的宽度 与字体的长度有关，与字体的大小有关，用画笔来测量
            val bounds = Rect()
            // 获取文本的Rect
            mPaint.getTextBounds(mText, 0, mText!!.length, bounds)
            width = bounds.width() + paddingLeft + paddingRight
        }

        var height = MeasureSpec.getSize(heightMeasureSpec)
        if (heightMode == MeasureSpec.AT_MOST) {
            val bounds = Rect()
            mPaint.getTextBounds(mText, 0, mText!!.length, bounds)
            height = bounds.height() + paddingTop + paddingBottom
        }

        // 设置控件的宽高
        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // baseLine的计算
        val fontMetrics = mPaint.fontMetricsInt
        // dy：代表高度的一半到基线baseLine的距离
        // top：baseLine到文字顶部的距离，是个负值
        // bottom：baseLine到文字底部的距离，是个正值
        val dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
        val baseLine = height / 2 + dy
        val x = paddingLeft
        /**
         * x：开始的位置
         * y：基线baseLine的位置，需要去计算基线位置
         */
        canvas?.drawText(mText.toString(), x.toFloat(), baseLine.toFloat(), mPaint)
    }
}